package com.example.wac.controller;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.wac.annotation.CurrentLimiting;
import com.example.wac.annotation.UnJwtToken;
import com.example.wac.entity.User;
import com.example.wac.service.CommonService;
import com.example.wac.service.UserService;
import com.example.wac.util.OssUtil;
import com.example.wac.util.ThreadLocalUtils;
import com.example.wac.vo.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author wuancheng
 */
@Slf4j
@RestController
@RequestMapping("/common")
public class CommonController {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    CommonService commonService;

    @Autowired
    ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 上传文件至oss
     *
     * @param file
     * @return 返回下载文件的url
     */
    @UnJwtToken
    @PostMapping("/upload_file")
    public ApiResult upload(@RequestParam("file") MultipartFile file){
        return OssUtil.uploadFile(file);
    }

    /**
     * 上传文件至oss
     *
     * @param file
     * @return 返回文件预览的url
     */
    @UnJwtToken
    @PostMapping("/preview_upload_file")
    public ApiResult previewUpload(@RequestParam("file") MultipartFile file){
        return OssUtil.previewUploadFile(file);
    }

    /**
     * 下载文件从oss
     *
     * @param fileName
     * @return
     */
    @UnJwtToken
    @PostMapping("/download_file")
    public ApiResult downLoadFile(@RequestParam("fileName") String fileName){
        return OssUtil.downLoadFile(fileName);
    }

    /**
     * 上传文件至本地
     *
     * @param fileName
     * @return
     */
    @UnJwtToken
    @PostMapping("/upload_local_file")
    public ApiResult upLoadLocalFile(@RequestParam("fileName") MultipartFile fileName){
        return commonService.upLoadLocalFile(fileName);
    }

    /**
     * 上传文件至本地
     *
     * @param fileName
     * @return
     */
    @UnJwtToken
    @PostMapping("/upload_local_file_transfer")
    public ApiResult upLoadLocalFileTransfer(@RequestParam("fileName") MultipartFile fileName){
        return commonService.upLoadLocalFileTransfer(fileName);
    }

    /**
     * 下载本地文件
     *
     * @param response
     * @return
     */
    @UnJwtToken
    @GetMapping("/download_local_file")
    public void downLoadLocalFile(HttpServletResponse response , @RequestParam("fileName") String fileName){
        commonService.downLoadLocalFile(response,fileName);
    }

    /**
     * 判断文件是否存在oss中
     *
     * @param fileNameFullPath
     * @return
     */
    @UnJwtToken
    @GetMapping("/file-exist")
    public ApiResult fileExist(@RequestParam("fileNameFullPath") String fileNameFullPath){
        ApiResult apiResult = OssUtil.fileFlag(fileNameFullPath);
        return apiResult;
    }

    /**
     * restTemplate调用外部url
     *
     * @return
     */
    @UnJwtToken
    @GetMapping("/doGet")
    public ApiResult doGetReturnMap(){
        Map resultMap = restTemplate.getForObject("http://172.30.61.83:8088/email/list", Map.class);
        String string = JSONObject.toJSONString(resultMap);
        return ApiResult.success(string);
    }

    @UnJwtToken
    @PostMapping("/request")
    public ApiResult getRequest(HttpServletRequest request,@RequestBody Map<String, Object> map){
        HashMap<Object, Object> resultMap = new HashMap<>(16);
        String method = request.getMethod();
        String remoteAddr = request.getRemoteAddr();
        String localAddr = request.getLocalAddr();
        String requestURI = request.getRequestURI();
        String protocol = request.getProtocol();
        String contextPath = request.getContextPath();
        String user = request.getHeader("user");
        String param = request.getParameter("param");
        String characterEncoding = request.getCharacterEncoding();
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            log.info("key:" + entry.getKey() + "value:" + entry.getValue());
        }
        map.put("method", method);
        map.put("remoteAddr", remoteAddr);
        map.put("localAddr", localAddr);
        map.put("requestURI", requestURI);
        map.put("protocol", protocol);
        map.put("contextPath", contextPath);
        map.put("user", user);
        map.put("param", param);
        map.put("characterEncoding", characterEncoding);
        return ApiResult.success(map);
    }

    @UnJwtToken
    @PostMapping("/doGetByHttpUtil")
    public ApiResult doGetByHttpUtil(@RequestBody Map<String,String> dto){
        String url = dto.get("url");
        String doGet = HttpUtil.get(url, (Map<String, Object>) null);
//        JSONObject jsonObject = JSONObject.parseObject(doGet);
//        Object data = jsonObject.get("data");
//        String toJSONString = JSONObject.toJSONString(data);
//        List<Email> email = JSONObject.parseArray(toJSONString, Email.class);
        Map map = JSONObject.parseObject(doGet, Map.class);
        return ApiResult.success(map);
    }

    @UnJwtToken
    @PostMapping("/threadLocal")
    public ApiResult threadLocalTest(@RequestBody Map<String,String> dto, HttpServletRequest request){
        request.setAttribute("name", "hk");
        String object = dto.get("object");
        ThreadLocalUtils.setThreadLocal(object);
        log.info("hello");
        return ApiResult.success(ThreadLocalUtils.getAndRemove());
    }

    @UnJwtToken
    @GetMapping("/async")
    public ApiResult asyncTest(){
        threadPoolTaskExecutor.execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("5秒后我异步输出啦");
        });
        return ApiResult.success("可以了");
    }

    @UnJwtToken
    @GetMapping("/response")
    public void responseTest(HttpServletResponse response){
        try {
            String s = "你好";
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(s.getBytes());
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @UnJwtToken
    @GetMapping("/argumentResolver")
    public ApiResult argumentResolverTest(User user){
        return ApiResult.success(user);
    }

    @Autowired
    UserService userService;

    @UnJwtToken
    @GetMapping("/userServiceTest")
    public ApiResult userServiceTest(){
        return ApiResult.success(userService.list(1,1));
    }

    @CurrentLimiting("getResult")
    @UnJwtToken
    @GetMapping("/web/interceptor")
    public ApiResult getResult(){
        return ApiResult.success(123456);
    }
}
